package top.likeqc.blog.service.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.likeqc.blog.NotFoundException;
import top.likeqc.blog.dao.BlogRepository;
import top.likeqc.blog.pojo.Blog;
import top.likeqc.blog.pojo.Type;
import top.likeqc.blog.service.BlogService;
import top.likeqc.blog.vo.BlogQuery;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author likeqc.top
 * @date 2021/4/17 13:21
 */
@Service
@Transactional
public class BlogServiceImpl implements BlogService {

    @Autowired private BlogRepository blogRepository;

    @Override
    public Blog getBlog(Long id) {
        // return blogRepository.getOne(id);
        return blogRepository.findById(id).get();
    }

    /**
     * 根据条件查询博客
     *
     * @param pageable 分页
     * @param blog 查询条件
     * @return 查询结果
     */
    @Override
    public Page<Blog> listBlog(Pageable pageable, BlogQuery blog) {
        // 使用 JpaSpecificationExecutor 接口，动态查询
        return blogRepository.findAll(
                new Specification<Blog>() {
                    @Override
                    public Predicate toPredicate(
                            Root<Blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {

                        List<Predicate> predicates = new ArrayList<>();
                        if (blog.getTitle() != null && !"".equals(blog.getTitle())) {
                            predicates.add(
                                    cb.like(root.<String>get("title"), "%" + blog.getTitle()));
                        }
                        if (blog.getTypeId() != null) {
                            predicates.add(
                                    cb.like(
                                            root.<Type>get("type").get("id"),
                                            "%" + blog.getTypeId()));
                        }
                        if (blog.isRecommend()) {
                            predicates.add(
                                    cb.equal(
                                            root.<Boolean>get("recommend"), blog.isRecommend()));
                        }
                        cq.where(predicates.toArray(new Predicate[predicates.size()]));
                        return null;
                    }
                },
                pageable);
    }

    @Override
    public Blog saveBlog(Blog blog) {
        return blogRepository.save(blog);
    }

    @Override
    public Blog updateBlog(Long id, Blog blog) {
        Optional<Blog> result = blogRepository.findById(id);
        if (!result.isPresent()) {
            throw new NotFoundException("该博客不存在");
        }
        Blog b = result.get();
        BeanUtils.copyProperties(blog, b);
        return blogRepository.save(b);
    }

    @Override
    public void deleteBlog(Long id) {
        blogRepository.deleteById(id);
    }
}
